package com.myapp.Data;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.facebook.react.bridge.WritableMap;
import com.gizwits.gizwifisdk.api.GizWifiDevice;
import com.gizwits.gizwifisdk.enumration.GizWifiErrorCode;
import com.gizwits.gizwifisdk.listener.GizWifiDeviceListener;
import com.google.gson.Gson;
import com.myapp.EventBus.EventBusUtil;
import com.myapp.EventBus.GizMessageEvent;
import com.myapp.MainApplication;
import com.myapp.RN.OpenNativeModule;
import com.myapp.utils.HexStrUtils;

import java.util.concurrent.ConcurrentHashMap;

/**
 * author : YuFeng
 * e-mail : 923462992@qq.com
 * date   : 2019/8/7 16:55
 * desc   :
 */
public class GizManger {
    private static final String TAG = "GizManger";
    private Toast mToast;
    private GizWifiDevice mDevice;
    private Context mContext;
    ConcurrentHashMap<String,Object> dataMap = new ConcurrentHashMap<String, Object>();

    // 数据点"SystemPower"对应的标识名
    private static final String KEY_SYSTEMPOWER = "SystemPower";
    // 数据点"SystemFan"对应的标识名
    private static final String KEY_SYSTEMFAN = "SystemFan";
    // 数据点"ErrorImfor"对应的标识名
    private static final String KEY_ERRORIMFOR = "ErrorImfor";
    // 数据点"RoomTemp"对应的标识名
    private static final String KEY_ROOMTEMP = "RoomTemp";
    // 数据点"SaunaRunTime"对应的标识名
    private static final String KEY_SAUNARUNTIME = "SaunaRunTime";
    // 数据点"SystemLight"对应的标识名
    private static final String KEY_SYSTEMLIGHT = "SystemLight";
    // 数据点"SaunaStateTimeTemp"对应的标识名
    private static final String KEY_SAUNASTATETIMETEMP = "SaunaStateTimeTemp";
    // 数据点"FMBT_StateFreqVol"对应的标识名
    private static final String KEY_FMBT_STATEFREQVOL = "FMBT_StateFreqVol";
    // 数据点"FMBT_16_Freq"对应的标识名
    private static final String KEY_FMBT_16_FREQ = "FMBT_16_Freq";

    // 数据点"SystemPower"对应的存储数据
    private static boolean data_SystemPower;
    // 数据点"SystemFan"对应的存储数据
    private static boolean data_SystemFan;
    // 数据点"ErrorImfor"对应的存储数据
    private static int data_ErrorImfor;
    // 数据点"RoomTemp"对应的存储数据
    private static int data_RoomTemp;
    // 数据点"SaunaRunTime"对应的存储数据
    private static int data_SaunaRunTime;
    // 数据点"SystemLight"对应的存储数据
    private static byte[] data_SystemLight;
    // 数据点"SaunaStateTimeTemp"对应的存储数据
    private static byte[] data_SaunaStateTimeTemp;
    // 数据点"FMBT_StateFreqVol"对应的存储数据
    private static byte[] data_FMBT_StateFreqVol;
    // 数据点"FMBT_16_Freq"对应的存储数据
    private static byte[] data_FMBT_16_Freq;

    private static class GizHolder{
        public static final GizManger instance = new GizManger();
    }

    public static GizManger getInstance() {
        return GizHolder.instance;
    }

    private GizManger() {}

    public void init(Context context) {
        this.mContext = context;
    }

    public void setDevice(GizWifiDevice device) {
        mDevice = device;
        mDevice.setListener(mListener);
    }

    public GizWifiDevice getDevice() {
        return mDevice;
    }


    private GizWifiDeviceListener mListener = new GizWifiDeviceListener() {
        @Override
        public void didReceiveData(GizWifiErrorCode result, GizWifiDevice device, ConcurrentHashMap<String, Object> dataMap, int sn) {
            if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS&& dataMap.get("data") != null) {
                // 透传数据，无数据点定义，适合开发者自行定义协议自行解析

                getDataFromReceiveDataMap(dataMap);

                //还可以用handler.sendEmptyMessage
                EventBusUtil.postSync(new GizMessageEvent(this));

                if (dataMap.get("binary") != null) {
                    byte[] binary = (byte[]) dataMap.get("binary");


                    //Log.i("info", "Binary data:" + bytesToHex(binary))
                    // 收到后面需要自行解析
                }
            }
        }
    };

    private void GizWrite(byte[] sendByte,OnWriteInterface callback) {
        dataMap.put("binary", sendByte);
        mDevice.write(dataMap, 0);
        if (callback != null)
            callback.onWriteSuccess(sendByte);
    }


    public interface OnWriteInterface {
        void onWriteSuccess(byte[] sendByte);
        void onFailed(String msg);
    }

    /**
     * 发送指令,下发单个数据点的命令可以用这个方法
     *
     * <h3>注意</h3>
     * <p>
     * 下发多个数据点命令不能用这个方法多次调用，一次性多次调用这个方法会导致模组无法正确接收消息，参考方法内注释。
     * </p>
     *
     * @param key
     *            数据点对应的标识名
     * @param value
     *            需要改变的值
     */
    public void sendCommand(String key, Object value) {
        if (value == null) {
            return;
        }
        int sn = 5;
        ConcurrentHashMap<String, Object> hashMap = new ConcurrentHashMap<String, Object>();
        hashMap.put(key, value);
        // 同时下发多个数据点需要一次性在map中放置全部需要控制的key，value值
        // hashMap.put(key2, value2);
        // hashMap.put(key3, value3);
        mDevice.write(hashMap, sn);
        Log.i("liang", "下发命令：" + hashMap.toString());
    }


    public WritableMap tranfor(){
        Gson gson = new Gson();
  //      GizData gizData = new GizData(new Giz(data_ErrorImfor,HexStrUtils.splitBytesString(HexStrUtils.bytesToHexString(data_FMBT_16_Freq),HexStrUtils.bytesToHexString(data_FMBT_StateFreqVol),"1",data_RoomTemp,
  //              data_SaunaRunTime,data_SaunaStateTimeTemp,data_SystemFan,data_SystemPower,1));
        Log.i("tranfor", "data_SystemPower: "+data_SystemPower);
        Log.i("tranfor", "data_SystemFan: "+data_SystemFan);
        Log.i("tranfor", "data_ErrorImfor: "+data_ErrorImfor);
        Log.i("tranfor", "data_RoomTemp: "+data_RoomTemp);
        Log.i("tranfor", "data_SaunaRunTime: "+data_SaunaRunTime);
        Log.i("tranfor", "data_SystemLight: "+HexStrUtils.bytesToHexString(data_SystemLight));
        Log.i("tranfor", "data_SaunaStateTimeTemp: "+HexStrUtils.bytesToHexString(data_SaunaStateTimeTemp));
        Log.i("tranfor", "data_FMBT_StateFreqVol: "+HexStrUtils.bytesToHexString(data_FMBT_StateFreqVol));
        Log.i("tranfor", "data_FMBT_16_Freq: "+HexStrUtils.splitBytesString(HexStrUtils.bytesToHexString(data_FMBT_16_Freq)));
        int imfor = data_ErrorImfor;
        String fmbt_16 = HexStrUtils.splitBytesString(HexStrUtils.bytesToHexString(data_FMBT_16_Freq));
        String fmbt_State = HexStrUtils.bytesToHexString(data_FMBT_StateFreqVol);
        String oneLight = "0";
        int roomTemp = data_RoomTemp;
        int SRTime = data_SaunaRunTime;
        String ssTimeTemp = HexStrUtils.bytesToHexString(data_SaunaStateTimeTemp);
        String systemFan = "0";
        String systemPower = "0";
        String twoLight = "0";
        if (data_SystemPower){
            systemPower ="1";
        } else {
            systemPower = "0";
        }

        if (data_SystemFan){
            systemFan = "1";
        } else {
            systemFan = "0";
        }

        if (HexStrUtils.bytesToHexString(data_SystemLight).equals("00")){
            oneLight = "0";
            twoLight = "0";
        }

        if (HexStrUtils.bytesToHexString(data_SystemLight).equals("01")){
            oneLight = "1";
            twoLight = "0";
        }

        if (HexStrUtils.bytesToHexString(data_SystemLight).equals("02")){
            oneLight = "0";
            twoLight = "1";
        }
        if (HexStrUtils.bytesToHexString(data_SystemLight).equals("03")){
            oneLight = "1";
            twoLight = "1";
        }
        Giz giz = new Giz(imfor,fmbt_16,fmbt_State,oneLight,
                roomTemp,SRTime,ssTimeTemp,systemFan,systemPower,twoLight);
//        WritableMap sendMap =
//        String gizJson = gson.toJson(giz);
//        String json = gizJson.replaceAll("\"(\\w+)\"(\\s*:\\s*)", "$1$2");
//        Log.i("tranfor", "gizJson: "+json);
//        ReadableMap map = new ReadableNativeMap();
        return giz.getAsWritableMap();
    }


    @SuppressWarnings("unchecked")
    protected void getDataFromReceiveDataMap(ConcurrentHashMap<String, Object> dataMap) {
        // 已定义的设备数据点，有布尔、数值和枚举型数据

        if (dataMap.get("data") != null) {
            ConcurrentHashMap<String, Object> map = (ConcurrentHashMap<String, Object>) dataMap.get("data");
            assert map != null;
            for (String dataKey : map.keySet()) {
                if (dataKey.equals(KEY_SYSTEMPOWER)) {
                    data_SystemPower = (Boolean) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+data_SystemPower);
                }
                if (dataKey.equals(KEY_SYSTEMFAN)) {
                    data_SystemFan = (Boolean) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+data_SystemFan);
                }
                if (dataKey.equals(KEY_ERRORIMFOR)) {
                    data_ErrorImfor = (Integer) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+data_ErrorImfor);
                }
                if (dataKey.equals(KEY_ROOMTEMP)) {
                    data_RoomTemp = (Integer) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+data_RoomTemp);
                }
                if (dataKey.equals(KEY_SAUNARUNTIME)) {
                    data_SaunaRunTime = (Integer) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+data_SaunaRunTime);

                }
                if (dataKey.equals(KEY_SYSTEMLIGHT)) {
                    data_SystemLight = (byte[]) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+HexStrUtils.bytesToHexString(data_SystemLight));

                }
                if (dataKey.equals(KEY_SAUNASTATETIMETEMP)) {
                    data_SaunaStateTimeTemp = (byte[]) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+HexStrUtils.bytesToHexString(data_SaunaStateTimeTemp));
                }
                if (dataKey.equals(KEY_FMBT_STATEFREQVOL)) {
                    data_FMBT_StateFreqVol = (byte[]) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+HexStrUtils.bytesToHexString(data_FMBT_StateFreqVol));

                }
                if (dataKey.equals(KEY_FMBT_16_FREQ)) {
                    data_FMBT_16_Freq = (byte[]) map.get(dataKey);
                    Log.i("dataChange", "getDataFromReceiveDataMap: "+HexStrUtils.splitBytesString(HexStrUtils.bytesToHexString(data_FMBT_16_Freq)));

                }
            }
        }

        StringBuilder sBuilder = new StringBuilder();

        // 已定义的设备报警数据点，设备发生报警后该字段有内容，没有发生报警则没内容
        if (dataMap.get("alerts") != null) {
            ConcurrentHashMap<String, Object> map = (ConcurrentHashMap<String, Object>) dataMap.get("alerts");
            for (String alertsKey : map.keySet()) {
                if ((Boolean) map.get(alertsKey)) {
                    sBuilder.append("报警:" + alertsKey + "=true" + "\n");
                }
            }
        }

        // 已定义的设备故障数据点，设备发生故障后该字段有内容，没有发生故障则没内容
        if (dataMap.get("faults") != null) {
            ConcurrentHashMap<String, Object> map = (ConcurrentHashMap<String, Object>) dataMap.get("faults");
            for (String faultsKey : map.keySet()) {
                if ((Boolean) map.get(faultsKey)) {
                    sBuilder.append("故障:" + faultsKey + "=true" + "\n");
                }
            }
        }

        if (sBuilder.length() > 0) {
            sBuilder.insert(0, "[设备故障或报警]\n");
            myToast(sBuilder.toString().trim());
        }

        // 透传数据，无数据点定义，适合开发者自行定义协议自行解析
        if (dataMap.get("binary") != null) {
            byte[] binary = (byte[]) dataMap.get("binary");
            Log.i("", "Binary data:" + HexStrUtils.bytesToHexString(binary));
        }
    }

    public void myToast(String string) {
        if (mToast != null) {
            mToast.setText(string);
        } else {
            mToast = Toast.makeText(mContext, string, Toast.LENGTH_LONG);
        }
        mToast.show();
    }

}
